import { findRoomHostiles } from "../global/map";
import { timerEnd, timerLog, timerStart } from "../util/log";
import { getActualResourceAmount } from "../util/store";
import { requireDefined } from "../util/util";

export const roleTower={
    findInvaders(room){
        if(room.__towerInvaders !== undefined){
            return room.__towerInvaders;
        }
        return room.__towerInvaders =  room.find(FIND_HOSTILE_CREEPS,{
            filter(creep){
                return creep.owner.username === 'Invader';
            }
        });
    },
    findDamagedCreeps(room){
        if(room.__towerDamagedCreeps != undefined){
            return room.__towerDamagedCreeps;
        }
        let targets = room.find(FIND_MY_CREEPS,{
            filter:(creep)=>{
                return creep.hits<creep.hitsMax;
            }
        });
        return room.__towerDamagedCreeps = targets.sort((a,b)=>a.hits/a.hitsMax-b.hits/b.hitsMax);
    },
    findDamagedStructures(room){
        if(room.__towerDamagedStructures != undefined){
            return room.__towerDamagedStructures;
        }
        let targets = room.find(FIND_STRUCTURES,{
            filter:(structure)=>{
                if(structure.hits >= structure.hitsMax){
                    return false;
                }
                if(structure.structureType === STRUCTURE_WALL || (structure.structureType === STRUCTURE_RAMPART && structure.my)){
                    return (structure.hits<structure.hitsMax) && (
                        structure.room.controller.level === 8 || 
                        structure.hits<500000  
                    );
                }

                return structure.my || 
                    structure.structureType === STRUCTURE_ROAD ||
                    structure.structureType === STRUCTURE_CONTAINER;
            }
        });
        return room.__towerDamagedStructures = targets.sort((a,b)=>a.hits-b.hits);
    },

    /**
     * 
     * @param {StructureTower} tower 
     */
    run:function(tower){
        if(getActualResourceAmount(tower)<10){
            return ERR_NOT_ENOUGH_ENERGY;
        }
        let targets;
        let ret=ERR_NOT_FOUND;

        if(tower.room.__towerTarget !== undefined){
            let target = tower.room.__towerTarget;
            if((target instanceof Creep) && !target.my){
                ret = tower.attack(target);
            }else if(target instanceof Creep){
                ret = tower.heal(target);
            }else{
                ret = tower.repair(target);
            }
            return ret;
        }

        targets=this.findInvaders(tower.room);
        for(let target of targets){
            if(tower.attack(target) === OK){
                tower.room.__towerTarget = target;
                return OK;
            }
        }

        targets=this.findDamagedCreeps(tower.room);
        for(let target of targets){
            if((ret=tower.heal(target)) === OK){
                tower.room.__towerTarget = target;
                return OK;
            }
        }

        targets=this.findDamagedStructures(tower.room);
        for(let target of targets){
            ret = tower.repair(target);
            if(ret === OK){
                tower.room.__towerTarget = target;
                return OK;
            }
        }

        targets=findRoomHostiles(tower.room);
        for(let target of targets){
            if((ret = tower.attack(target)) === OK){
                tower.room.__towerTarget = target;
                return OK;
            }
        }

        return ret;
    }
}